package org.altervista.cp.thinjdbc.test;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import java.util.logging.LogManager;

import org.altervista.cp.thinjdbc.DefaultLoadQuery;
import org.altervista.cp.thinjdbc.Session;
import org.altervista.cp.thinjdbc.ds.DefaultDataSource;
import org.altervista.cp.thinjdbc.util.LogHelper;
import org.altervista.cp.thinjdbc.wrappers.Connection;
import org.altervista.cp.thinjdbc.wrappers.DataSource;
import org.altervista.cp.thinjdbc.wrappers.PreparedStatement;
import org.altervista.cp.thinjdbc.wrappers.ResultSet;

public class Main {

	private static final LogHelper logger = new LogHelper(Main.class);

	private static final String sql = "select employeeNumber, firstName, lastName "
			+ "from Employees";// where employeeNumber < ? ";

	private static final DefaultLoadQuery query = new DefaultLoadQuery(sql);

	private static final DefaultDataSource dds;
	private static final DataSource ds;

	static {

		String sampleDBPath = null;
		try {
			sampleDBPath = new File(new URL(Main.class.getClassLoader()
					.getResource(".")
					+ "../src/derby/BirtSample").getPath()).getAbsolutePath();
		} catch (MalformedURLException e) {
			e.printStackTrace();
			System.exit(1);
		}

		dds = new DefaultDataSource("org.apache.derby.jdbc.EmbeddedDriver",
				"jdbc:derby:" + sampleDBPath, "", "",
				// "jdbc:oracle:thin:@134.44.29.237:1521:DRGMGR10",
				// "drgmgrdba01","drgmgrdba01"
				null);

		ds = DataSource.newInstance(dds);

		String config = "handlers = java.util.logging.ConsoleHandler\n"
				+ ".level = ALL\n"
				+ "java.util.logging.ConsoleHandler.level = FINEST\n"
				+ "java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter";
		try {
			LogManager.getLogManager().readConfiguration(
					new ByteArrayInputStream(config.getBytes()));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		ds.setRetriesOnError(5);
	}

	public static void main(String[] args) {
		for (int i = 1; i > 0; i--) {
			new TestThread0(i).start();
		}
	}

	private static class TestThread2 extends Thread {
		int _index;

		TestThread2(int index) {
			_index = index;
		}

		public void run() {
			try {
				Thread.sleep(_index / 2);
			} catch (InterruptedException e) {
			}

			logger.info("\n*** START THREAD [{0}] ***", String.valueOf(_index));

			Session session = new Session(ds.getConnection());
			session.setCommitTransactionOnClose(true);
			session.begin();
			session.close();

			logger.info("\n*** STOP THREAD [{0}] ***", String.valueOf(_index));
		}
	}

	private static class TestThread1 extends Thread {
		int _index;

		TestThread1(int index) {
			_index = index;
		}

		public void run() {
			try {
				Thread.sleep(_index / 2);
			} catch (InterruptedException e) {
			}

			logger.info("\n*** START THREAD [{0}] ***", String.valueOf(_index));

			Session session = new Session(ds.getConnection());
			session.setCommitTransactionOnClose(true);
			session.begin();

			int rnd = 200 + new Random().nextInt(300);
			query.setParameter(1, rnd);

			for (Map<String, Object> row : query.excecute()) {
				StringBuffer sb = new StringBuffer();
				for (Entry<String, Object> entry : row.entrySet()) {
					if (sb.length() != 0) {
						sb.append(" - ");
					}
					sb.append(entry.getKey().toUpperCase()).append(": ")
							.append(entry.getValue());
				}
				logger.info(sb.toString());
			}

			session.close();

			logger.info("\n*** STOP THREAD [{0}] ***", String.valueOf(_index));
		}
	}

	private static class TestThread0 extends Thread {
		int _index;

		TestThread0(int index) {
			_index = index;
		}

		public void run() {
			try {
				System.out.println("START THREAD [" + _index + "]");
				Thread.sleep(_index / 2);
			} catch (InterruptedException e) {
			}

			Connection cw = ds.getConnection();
			cw.setAutoCommit(false);
			PreparedStatement psw = cw.prepareStatement(sql);
			// System.out.println(((PreparedStatementWrapper4)
			// psw).isPoolable());
			// int rnd = new Random().nextInt(500);
			// psw.setInt(1, 200);
			ResultSet rsw = psw.executeQuery();

			while (rsw.next()) {
				StringBuffer sb = new StringBuffer();
				for (int i = 0, n = rsw.getMetaData().getColumnCount(); i < n; i++) {
					if (sb.length() != 0) {
						sb.append(" - ");
					}
					sb.append(
							rsw.getMetaData().getColumnName(i + 1)
									.toUpperCase()).append(": ").append(
							rsw.getString(i + 1));

				}
				logger.info(sb.toString());
			}
			logger.info("closing resultset");
			rsw.close();
			logger.info("closing statement");
			psw.close();
			logger.info("committing transaction");
			cw.commit();
			cw.setAutoCommit(true);
			logger.info("closing connection");
			cw.close();
		}
	}

	private static class TestThread00 extends Thread {
		int _index;

		TestThread00(int index) {
			_index = index;
		}

		public void run() {
			try {
				System.out.println("START THREAD [" + _index + "]");
				Thread.sleep(_index / 2);
			} catch (InterruptedException e) {
			}
			try {
				java.sql.Connection c = dds.getConnection();
				c.setAutoCommit(false);
				java.sql.PreparedStatement ps = c.prepareStatement(sql);
				// System.out.println(((PreparedStatementWrapper4)
				// psw).isPoolable());
				int rnd = new Random().nextInt(500);
				ps.setInt(1, rnd);
				java.sql.ResultSet rs = ps.executeQuery();

				while (rs.next()) {
					StringBuffer sb = new StringBuffer();
					for (int i = 0, n = rs.getMetaData().getColumnCount(); i < n; i++) {
						if (sb.length() != 0) {
							sb.append(" - ");
						}
						sb.append(
								rs.getMetaData().getColumnName(i + 1)
										.toUpperCase()).append(": ").append(
								rs.getString(i + 1));

					}
					logger.info(sb.toString());
				}
				logger.info("closing resultset");
				rs.close();
				logger.info("closing statement");
				ps.close();
				logger.info("committing transaction");
				c.commit();
				c.setAutoCommit(true);
				logger.info("closing connection");
				c.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}
